package io.openkunlun.javadsl.serialization;

import io.openkunlun.javadsl.v1.DaprSerializationProtos;

import java.io.IOException;

public abstract class DelegatingSerializer implements DaprSerializer {

    @Override
    final public byte[] serialize(Object o) throws IOException {
        DaprSerializationProtos.SerializationManifest manifest = serializeWithManifest(o);
        return manifest.toByteArray();
    }

    /**
     * @param o
     * @return
     */
    protected abstract DaprSerializationProtos.SerializationManifest serializeWithManifest(Object o) throws IOException;

    @Override
    final public <T> byte[] serialize(Object o, DaprObject<T> type) throws IOException {
        DaprSerializationProtos.SerializationManifest manifest = serializeWithManifest(o, type);
        return manifest.toByteArray();
    }

    /**
     * @param o
     * @param type
     * @param <T>
     * @return
     */
    protected abstract <T> DaprSerializationProtos.SerializationManifest serializeWithManifest(Object o, DaprObject<T> type) throws IOException;

    @Override
    final public <T> T deserialize(byte[] data, Class<T> type) throws IOException {
        DaprSerializationProtos.SerializationManifest manifest = DaprSerializationProtos.SerializationManifest.parseFrom(data);
        return deserializeWithManifest(manifest, type);
    }

    /**
     * @param manifest
     * @param type
     * @param <T>
     * @return
     */
    protected abstract <T> T deserializeWithManifest(DaprSerializationProtos.SerializationManifest manifest, Class<T> type) throws IOException;

    @Override
    final public <T> T deserialize(byte[] data, DaprObject<T> type) throws IOException {
        DaprSerializationProtos.SerializationManifest manifest = DaprSerializationProtos.SerializationManifest.parseFrom(data);
        return deserializeWithManifest(manifest, type);
    }

    /**
     * @param manifest
     * @param type
     * @param <T>
     * @return
     */
    protected abstract <T> T deserializeWithManifest(DaprSerializationProtos.SerializationManifest manifest, DaprObject<T> type) throws IOException;
}
